#include "msgPackage.h"
#include "serialportdefine.h"

#include <cstring>

// 发送数据封装类
CMsgPackage::CMsgPackage()
{
}

/*****************************************
 *  查询类报文封装总函数
 *   sendMsgPointer                    将要发送的报文
 *   sendMsgLen                        将要发送报文的长度
 *   dstNodeId                         报文目的节点
 *   linkType                          通信链路，通信手段
 *   mainMsgType                       报文类型
 *   subMsgType                        子报文类型
 *
 ******************************************/
int CMsgPackage::QueryMsgPackage(char *sendMsgPointer, unsigned char & sendMsgLen, unsigned char dstNodeId,
                               unsigned char linkType, unsigned char mainMsgType, unsigned char subMsgType)
{
    char dataContent[10];
    unsigned char dataContentLength = 0;

    if ( 0 == sendMsgPointer )
    {
        return -1;
    }
    // 配置、查询类指令
    commonParamQuery(dataContent , dataContentLength , subMsgType);
    // 基本消息封装函数
    basicMsgPackage(dataContent , dataContentLength , mainMsgType , sendMsgPointer , sendMsgLen , dstNodeId , linkType );
    return 1;
}

// 唤醒、待机和复位远程控制类指令
int CMsgPackage::commonParamQuery(char *msgPointer, unsigned char &msgLen, unsigned char subMsgType)
{
    if ( 0 == msgPointer )
    {
        return -1;
    }

    memset(msgPointer , subMsgType , 1);
    msgLen = 1;

    return 1;
}


/*****************************************
 *  基本消息封装函数
 *   srcMsgPointer                     数据内容
 *   srcMsgLen                         数据内容长度
 *   mainMsgType                       报文类型
 *   dstMsgPointer                     输出报文（完成封装以后的报文）
 *   dstMsgLength                      输出报文长度
 *   dstNodeId                         报文目的节点
 *   linkType                          通信链路
 ******************************************/
int CMsgPackage::basicMsgPackage(char * srcMsgPointer , unsigned char srcMsgLen , unsigned char mainMsgType ,
                                 char * dstMsgPointer , unsigned char & dstMsgLength , unsigned char dstNodeId ,
                                 unsigned char linkType )
{
    if ( (0 == srcMsgPointer) || (0 == dstMsgPointer) )
        return -1;
    // 报头
    memset(dstMsgPointer , 0xEE , 1);
    memset(dstMsgPointer+1 , 0xA5 , 1);
    memset(dstMsgPointer+2 , 0x5A , 1);
    dstMsgLength = 9 + srcMsgLen;
    // 报文长度
    memset(dstMsgPointer+3 , dstMsgLength , 1);
    // 通讯手段
    memset(dstMsgPointer+4 , linkType , 1);
    // 发送端
    memset(dstMsgPointer+5 , 0xFF , 1);
    // 接收端
    memset(dstMsgPointer+6 , dstNodeId , 1);
    // 报文类型
    memset(dstMsgPointer+7 , mainMsgType , 1);
    // 数据内容
    memcpy( dstMsgPointer + 8 , srcMsgPointer , srcMsgLen );
    // 校验和
    memset(dstMsgPointer + 8 + srcMsgLen , checkSum(dstMsgPointer , 8+srcMsgLen) , 1);

    return 0;
}

// 计算校验和
unsigned char CMsgPackage::checkSum(char *msgPointer, unsigned char msgLength)
{
    unsigned char t_checksum = 0;
    for ( int i = 0 ; i < msgLength ; ++i )
    {
        t_checksum = t_checksum + *(unsigned char *)(msgPointer+i);
    }

    return t_checksum;
}
